#pragma once
#include "actor.hpp"
#include "land.hpp"
#include "config.hpp"
#include "command-func.hpp"
#include <vector>
#include <unordered_map>
class Actor;
class Displayer;

class Game
{
    friend class Displayer;
    friend class Actor;
    friend std::string CommandFuncDump(std::string cmd, Game *g_ptr);
    friend std::string CommandFuncPreset(std::string cmd, Game *g);

private:
    size_t m_user_num{0};
    std::string m_user_order;
    Actor m_actor[MAX_USER_NUM];
    Land m_land[LAND_NUM];
    int m_current_user{0};
    std::unordered_map<char, int> m_name2idx;

    std::string m_input_tip;
    Displayer *m_display{nullptr};
    int m_die_cnt{0};
    int m_tip_idx{0};
    std::vector<std::string> m_tip_queue;
    bool m_tip_clear{false};
    int m_default_fund{10000};
    bool m_gameover{false};

public:
    CommandFunc m_cfunc;
    Game(void);
    virtual ~Game(void);
    void InitLand(void);
    void SetDisplayer(Displayer *dis);
    void ResetGame(void);
    void SetDefaultFund(int f);

    bool SetUser(std::string);
    std::string GetUser(void);
    bool SetCurrentUser(int cur_user);                   //设置当前玩家
    bool SetCurrentUser(char cur_user);                  //设置当前玩家
    int GetCurrentUser(void);                            //获得当前玩家
    bool SetUserLocation(char user, int loc, int delay); //设置玩家位置
    bool SetLandOwner(char user, int loc, int level);    //设置地所属及房屋等级
    bool SetFund(char user, int num);                    //设置玩家钱
    bool SetCredit(char user, int num);                  //设置玩家点数
    bool SetBarrierNum(char user, int num);              //设置玩家路障数
    bool SetRobotNum(char user, int num);                //设置玩家机器人数
    bool SetGodNum(char user, int num);                  //设置福神回合
    bool PlaceBarrier(int loc);                          //放障碍
    bool PlaceRobot(int loc);                            //放robot
    bool SellLand(char user, int loc);

    int ActorStep(Actor &actor); //角色执行一步，如果破产返回true
    bool Step(void);             //游戏进行一步，结束返回
    void UpdateDisplay(void);
    void ClearInputTip(void);
    void FullScreenTip(std::string s);
    void SetTip(std::string s);
    void SetInputTip(std::string s);
    bool Ready(void);
};